package com.hn658.base.message.appinfo.service.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;




import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.hn658.base.message.appinfo.dao.db.IAppMqDBDAO;
import com.hn658.base.message.appinfo.dao.redis.IAppMqRedisDAO;
import com.hn658.base.message.appinfo.entity.AppMqConfigEO;
import com.hn658.base.message.appinfo.enums.QueueType;
import com.hn658.base.message.appinfo.exception.AppMqException;
import com.hn658.base.message.appinfo.service.IAppMqService;
import com.hn658.framework.common.AbstractBusinessObject;
import com.hn658.framework.dataaccess.pagination.GenericPage;
import com.hn658.framework.logging.enums.LogCategory;
import com.hn658.framework.shared.exception.BusinessException;


/**
 * 应用业务逻辑实现类
 * 
 * 
 */
@Service
public class AppMqServiceImpl extends AbstractBusinessObject implements
		IAppMqService {

	@Autowired
	private IAppMqDBDAO appMqDBDAO;

	@Autowired
	private IAppMqRedisDAO appMqRedisDAO;

	
	
	@Override
	public List<AppMqConfigEO> findAppMqByIds(List<Long> ids) {
		return appMqDBDAO.selectByIds(ids);
	}
	
	@Override
	public GenericPage<AppMqConfigEO> queryAppMq(Map<String, Object> queryMap,
			int limit, int start, String sortBy, boolean isAsc) {
		if (StringUtils.isEmpty(sortBy)) {
			sortBy = "ID";
		}
		return appMqDBDAO.selectByMap(queryMap, limit, start, sortBy, isAsc);
	}

	@Override
	@Transactional
	public AppMqConfigEO addAppMq(AppMqConfigEO appMq){
		if (appMq == null) {
			throw new AppMqException(AppMqException.AppMqEmpty);
		}
		if (appMq.getQueueType() == null) {
			throw new AppMqException(AppMqException.AppMqTypeEmpty);
		}
		if(selectIsUniqueName(appMq.getId(),appMq.getQueueName())){
			//不能存在同名队列
			throw new AppMqException(AppMqException.AppMqNameIsExist);
		}
		if(selectIsUnique(appMq.getId(),appMq.getAppId(),appMq.getQueuePriority())){
			//同一个应用中队列优先级唯一
			throw new AppMqException(AppMqException.AppMqPriorityIsExist);
		}
		int countByAppId = countByAppId(appMq.getAppId());
		String queueNumber=appMq.getAppId()+"_"+countByAppId;
		appMq.setQueueNumber(queueNumber);
		appMq.setIsDeleted(false);
		appMq.setCreateTime(new Date());
		appMq.setLastUpdateTime(new Date());
		appMqDBDAO.insert(appMq);
		return appMq;
	}
	
	/**
	 * 判断是否存在同名队列
	 * @param queueName 队列名称
	 * @return
	 */
	public boolean selectIsUniqueName(Long id,String queueName){
		Map<String, Object> map=new HashMap<String, Object>();
		map.put("queueName", queueName);
		List<AppMqConfigEO> list = appMqDBDAO.selectByMap(map);
		if(list.size()<1){
			return false;
		}else {
		   if(list.get(0).getId().equals(id)){
			   return false; 
		   }
		}
		return true;
	}
	
	/**
	 * 判断是否存在同名队列
	 * @param queueName 队列名称
	 * @return
	 */
	public boolean selectIsUnique(Long id,String appId,Integer queuePriority){
		Map<String, Object> map=new HashMap<String, Object>();
		map.put("appId", appId);
		map.put("queuePriority", queuePriority);
		List<AppMqConfigEO> list = appMqDBDAO.selectByMap(map);
		if(list.size()<1){
			return false;
		}else {
		   if(list.get(0).getId().equals(id)){
			   return false; 
		   }
		}
		return true;
	}
	/**
	 * 同一个应用中队列个数
	 * @param appId 应用Id
	 * @return
	 */
	public int countByAppId(String appId){
		Map<String, Object> map=new HashMap<String, Object>();
		map.put("appId", appId);
		int i = appMqDBDAO.countByMap(map);
		return i;
	}
	@Override
	public AppMqConfigEO findAppMqById(Long id){
		if(id==null){
			throw new BusinessException(AppMqException.IdNotEmpty);
		}
		// 先从Redis中查询应用信息
		AppMqConfigEO appMq = appMqRedisDAO.findAppMqById(id);

		// 如Redis中为找到对应应用信息，则尝试去DB中查找
		if (null == appMq) {
			logger.debug(LogCategory.USER, "在redis中未找到{}相关信息，尝试在数据库中查找。", id);
			appMq = appMqDBDAO.selectById(Long.valueOf(id));
			// 如过在DB中找到对应信息返回，并将信息存入Redis中
			if (null != appMq) {
				logger.debug(LogCategory.USER, "在数据库中查找到{}相关信息，重新讲该信息存储到Redis。", id);
				appMqRedisDAO.saveAppMq(appMq);
			}
		} else {
			logger.debug(LogCategory.USER, "成功的在redis中找到{}相关信息。", id);
		}
		return appMq;
	}

	@Override
	public boolean deleteAppMqById(Long Id){
		if(null==Id){
			throw new AppMqException(AppMqException.IdNotEmpty);	
		}
		if(1==appMqDBDAO.deleteById(Id)){
			return true;
		}
		return false;
	}

	@Override
	public void disableAppMq(Long id){
		if(StringUtils.isEmpty(String.valueOf(id))){
			throw new BusinessException(AppMqException.IdNotEmpty);
		}
		AppMqConfigEO appMq=appMqDBDAO.selectById(id);
		if(null==appMq){
			throw new BusinessException(AppMqException.AppMqEmpty);
		}
		appMq.setLastUpdateTime(new Date());
		appMq.setEndTime(new Date());
		appMq.setIsDeleted(true);
		appMqDBDAO.update(appMq);
		appMqRedisDAO.deleteAppMq(id);
	}

	@Override
	public void enableAppMq(Long id){
		if(StringUtils.isEmpty(String.valueOf(id))){
			throw new BusinessException(AppMqException.IdNotEmpty);
		}
		AppMqConfigEO appMq=appMqDBDAO.selectById(id);
		if(null==appMq){
			throw new BusinessException(AppMqException.AppMqEmpty);
		}
		appMq.setLastUpdateTime(new Date());
		appMq.setEndTime(null);
		appMq.setIsDeleted(false);
		appMqDBDAO.update(appMq);
		appMqRedisDAO.deleteAppMq(id);
	}

	@Override
	public AppMqConfigEO modifyAppMq(AppMqConfigEO appMq){
		if (appMq == null) {
			throw new AppMqException(AppMqException.AppMqEmpty);
		}
		AppMqConfigEO dbAppMq = appMqDBDAO.selectById((Long) appMq.getId());
		if(selectIsUnique(appMq.getId(),appMq.getAppId(),appMq.getQueuePriority())){
			//同一个应用中队列优先级唯一
			throw new AppMqException(AppMqException.AppMqPriorityIsExist);
		}
		if (appMq.getQueuePriority()!=null) {
			dbAppMq.setQueuePriority(appMq.getQueuePriority());
		}
		if (StringUtils.isNotBlank(appMq.getQueueName())) {
			//若应用名称不为空，则检查数据库中是否已经存在同名应用，若存在则抛出异常
		    if(selectIsUniqueName(appMq.getId(),appMq.getQueueName())){
	            	throw new AppMqException(AppMqException.AppMqNameIsExist);
	        }
		    dbAppMq.setQueueName(appMq.getQueueName());
		}
		if (StringUtils.isNotBlank(String.valueOf(appMq.getIsDeleted()))) {
			dbAppMq.setIsDeleted(appMq.getIsDeleted());
		}
		if (appMq.getQueueType()!=null) {
			dbAppMq.setQueueType(appMq.getQueueType());
		}
		dbAppMq.setLastUpdateTime(new Date());
		appMqDBDAO.update(dbAppMq);
		appMqRedisDAO.deleteAppMq(dbAppMq.getId());
		return dbAppMq;
		
	}
	public List<AppMqConfigEO> findMqAll(){
		Map<String, Object> map=new HashMap<String, Object>();
		map.put("isDeleted", false);
		return appMqDBDAO.selectByMap(map);
	}

	@Override
	public AppMqConfigEO queryUniqueMqConfig(Map<String, Object> queryMap) {
		List<AppMqConfigEO> list = appMqDBDAO.selectByMap(queryMap);
		AppMqConfigEO configEO=null;
		if(list!=null&&list.size()>0){
			configEO=list.get(0);
		}
		return configEO;
	}
	
}
